package com.ccdt.tv.smartrecommend.utils;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.Utils;
import com.ccdt.tv.smartrecommend.Constant;
import com.dvb.auth.service.GetTokenService;
import com.google.gson.Gson;

import org.json.JSONException;
import org.json.JSONObject;


/**
 * Created by StormSun on 14,七月,2016
 */
public class GetTokenServiceHelper {
    private static final String TAG = "GetTokenServiceHelper";

    private GetTokenServiceHelper() {
    }

    private static GetTokenServiceHelper mInstance;
    private GetTokenService mService;
    private Context mContext;
    private String caCardId = null;
    private static final String SERVICE_ACTION = "com.dvb.auth.service.GetTokenService";

    private void reBind() {
        try {
            mContext.unbindService(connection);
            connection = null;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bind(mContext);
        }
    }

    public class CaInfo {
        public String caId;
        public String areaCode;
        public String tradeInfo;

        private CaInfo(String caId, String areaCode) {
            this.caId = caId;
            this.areaCode = areaCode;
        }

        public CaInfo(String caId, String areaCode, String tradeInfo) {
            this(caId, areaCode);
            this.tradeInfo = tradeInfo;
        }

        @Override
        public String toString() {
            return "CaInfo{" +
                    "caId='" + caId + '\'' +
                    ", areaCode='" + areaCode + '\'' +
                    ",  tradeInfo='" + tradeInfo + '\'' +
                    '}';
        }
    }

    public CaInfo getCaInfo() {
        if ( mService == null) {
            bind(mContext);
            Log.i(TAG,"get area code fail mService not bind");
            return null;
        }

        CaInfo ret = null;
        if (!flashCaCardInfo())
            // 获取异常则返回null
            return null;

        /*
        {
        "areaCode":"哈尔滨市",
        "balance":"90.00",
        "caId":"1234567890",
        "custId":"1234567890",
        "custName":"张三",
        "firstFlag":"0",
        "retrunMsg":"成功",
        "returnCode":"0",
        "userId":"1234567890"}
         */
        try {
           String userInfo = mService.getUserInfo();
            Log.i(TAG,"AAA userInfo >>> " + userInfo);
            JSONObject jsonObject = new JSONObject(userInfo);
            String areaCode = jsonObject.optString("areaCode");
            String caCard=jsonObject.optString("caId");
            SPUtils.getInstance(Constant.SP_NAME).put(Constant.SP_CA_INFO, new Gson().toJson(ret));
            ret= new CaInfo(caCard,areaCode);
        } catch (RemoteException e) {
            Log.i(TAG,"get area code fail RemoteException");
            e.printStackTrace();
            reBind();
        } catch (JSONException e) {
            e.printStackTrace();
            Log.i(TAG,"get area code fail JSONException");
        }
        Log.i(TAG,"AAA ret area code >>> " + ret);
        return ret;
    }

    /**
     * 获取userInfo Json串
     * @return
     */
    public String getUserInfo(){
        String userInfo = "";
        try {
            userInfo = mService.getUserInfo();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return userInfo;
    }

    /**
     * 获取绑定的产品列表
     * @return
     */
    public String getProducts(){
        String products = "";
        try {
            products = mService.getProducts();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return products;
    }

    public static GetTokenServiceHelper getInstance() {
        if (mInstance == null) {
            synchronized (GetTokenServiceHelper.class) {
                if (mInstance == null) {
                    mInstance = new GetTokenServiceHelper();
                }
            }
        }
        return mInstance;
    }

    /*
    {"returnCode":"0000","token":"KsqopaOIias1"}

    3.1.2获取Token 的AIDL 接口
        package com.dvb.auth.service;
        interface GetTokenService{
        String getToken();
        }
        返回数据为json 格式，具体定义如下
        {
        "returncode":"0000",
        "token":"KsqopaOIias1"
        }
        返回数据说明:
        关键字含义具体意义
        returncode 返回码
        “0000”: 正常
        "1000": CA 卡未插入
        "1001": 机顶盒已停机
        "1002": 机顶盒机卡不匹配
        "1003": CA 卡信息不存在
        "9999": 网络连接失败
        token : Token 令牌 与AAA 通讯所需要的令牌
     */
    public String isAuth() {
        if (mService == null) {
            bind(mContext);
            Log.i(TAG, "----isAuth----  >>> mService is null, bind service");
            return "CA服务绑定失败，尝试重新绑定服务！";
        }
        flashCaCardInfo();

        String isAuth = "";

        String status = SystemPropUtil.getPropertiesString("dtv.ca.card_status", "-1");
        if (!"2".equals(status)) {
            isAuth = "CA 卡未插入";
        }

        if (isAuth.trim().length() > 0) {
            return isAuth;
        }

        try {
            String token = mService.getToken();
            Log.i(TAG, "get token >>> " + token);
            if (!TextUtils.isEmpty(token) && token.trim().length() > 0) {
                JSONObject jsonObject = new JSONObject(token);
                String returnCode = jsonObject.optString("returnCode");
                if ("0000".equals(returnCode)) {
                    isAuth = "0000";
                } else if ("1000".equals(returnCode)) {
                    isAuth = "CA 卡未插入";
                } else if ("1001".equals(returnCode)) {
                    isAuth = "机顶盒已停机";
                } else if ("1002".equals(returnCode)) {
                    isAuth = "机顶盒机卡不匹配";
                } else if ("1003".equals(returnCode)) {
                    isAuth = "CA 卡信息不存在";
                } else if ("9999".equals(returnCode)) {
                    isAuth = "网络连接失败";
                } else {
                    isAuth = "认证失败，原因未知(" + returnCode + ")";
                }
            }
        } catch (RemoteException e) {
//            isAuth = "认证失败，认证服务异常，重新绑定中...";
            isAuth = "";
            e.printStackTrace();
            reBind();
        } catch (JSONException e) {
            isAuth = "认证失败，token信息解析异常";
            e.printStackTrace();
        }
        Log.i(TAG, "----isAuth----  >>> " + isAuth);
        return isAuth;
    }

    public void bind(Context context) {

        try {
            if (context == null) {
                context = Utils.getApp().getApplicationContext();
            }
            initServiceConnection();
            Log.i(TAG, "onStartDraw bind service " + SERVICE_ACTION);
            this.mContext = context;
            Intent intent = new Intent(SERVICE_ACTION);
            this.mContext.bindService(intent, connection,
                    Service.BIND_AUTO_CREATE);
        } catch (Exception e) {
            Log.i(TAG, "bind: error!");
        }
    }

    public void unBind(Context context) {
        try {
            if (connection != null) {
                context.unbindService(connection);
                connection = null;
            }
        } catch (Exception e) {
            Log.i(TAG, "unBind error!");
            e.printStackTrace();
        }
    }


    private ServiceConnection connection;

    private void initServiceConnection() {
        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(final ComponentName name, final IBinder service) {
                Log.i(TAG, SERVICE_ACTION + " service bind success");
                mService = GetTokenService.Stub.asInterface(service);
                if (mServiceConnectListener != null) {
                    mServiceConnectListener.onConnected();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.i(TAG, SERVICE_ACTION + " service unbind");
                mService = null;
            }
        };
    }

    private ServiceConnectListener mServiceConnectListener;

    public GetTokenServiceHelper setServiceConnectListener(ServiceConnectListener listener) {
        this.mServiceConnectListener = listener;
        return this;
    }

    /**
     * 取卡号，依次从以下获取
     * 1、从3A中获取
     * 2、从系统属性中获取
     * 3、从SharedPreference冲获取
     *
     * @return
     */
    public String getCaidFromNetAndDisk() {
        LogUtils.e("getCaidFromNetAndDisk start");
        // 从3A中获取
        String cardId = getCardId();
        LogUtils.e("getCaidFromNetAndDisk getCardId => " + cardId);
        if (TextUtils.isEmpty(cardId)) {
            // 从系统属性中获取
            cardId = SystemPropUtil.getPropertiesString("dtv.ca.card_id","");
            LogUtils.e("getCaidFromNetAndDisk getPropertiesString => " + cardId);
            if (TextUtils.isEmpty(cardId) || cardId.trim().length() <= 0) {
                // 从SharedPreference冲获取
//                cardId = (String) SPUtil.get("AAA_carCode", "");
                LogUtils.e("getCaidFromNetAndDisk SharedPreference => " + cardId);
            }
        }
        return cardId;
    }

    public String getCardId() {
        if (mService == null) {
            bind(mContext);
            LogUtils.e("get card code fail mService not bind");
            return "";
        }
        /*
        {
        "areaCode":"哈尔滨市",
        "balance":"90.00",
        "caId":"1234567890",
        "custId":"1234567890",
        "custName":"张三",
        "firstFlag":"0",
        "retrunMsg":"成功",
        "returnCode":"0",
        "userId":"1234567890"}
         */
        String ret = "";
        try {
            String userInfo = mService.getUserInfo();
            LogUtils.d("AAA userInfo >>> " + userInfo);
            JSONObject jsonObject = new JSONObject(userInfo);
            ret = jsonObject.optString("caId");
        } catch (RemoteException e) {
            LogUtils.e("get card code fail RemoteException");
            e.printStackTrace();
            reBind();
        } catch (JSONException e) {
            e.printStackTrace();
            LogUtils.e("get card code fail JSONException");
        }
        LogUtils.d("AAA ret card code >>> " + ret);
        return ret;
    }

    public String getTradeInfo(){
        if (mService == null) {
            bind(mContext);
            LogUtils.e("get card code fail mService not bind");
            return "";
        }
        /*
        {
        "areaCode":"哈尔滨市",
        "balance":"90.00",
        "caId":"1234567890",
        "custId":"1234567890",
        "custName":"张三",
        "firstFlag":"0",
        "retrunMsg":"成功",
        "returnCode":"0",
        "userId":"1234567890"}
         */
        String ret = "";
        try {
            String userInfo = mService.getUserInfo();
            LogUtils.d("AAA userInfo >>> " + userInfo);
            JSONObject jsonObject = new JSONObject(userInfo);
            ret = jsonObject.optString("tradeInfo");
        } catch (RemoteException e) {
            LogUtils.e("get card code fail RemoteException");
            e.printStackTrace();
            reBind();
        } catch (JSONException e) {
            e.printStackTrace();
            LogUtils.e("get card code fail JSONException");
        }
        LogUtils.d("AAA ret card code >>> " + ret);
        return ret;
    }

    public interface ServiceConnectListener {
        void onConnected();
    }

    /**
     * 判断获取的CA卡信息
     * 是否获取到，是否有换卡，是否绑定成功等情况
     * @return
     */
    private boolean flashCaCardInfo() {
        try {
            String userInfo = mService.getUserInfo();
            JSONObject jsonObject = new JSONObject(userInfo);
            String caCard = jsonObject.optString("caId");
            if (!TextUtils.isEmpty(caCard) && !TextUtils.isEmpty(caCardId)) {
                //同时不为空，缓存新卡号
                String oldCardId = caCardId;
                caCardId = caCard;
                if (oldCardId.equals(caCardId)) //新卡号与老卡号相同
                    return true;
                else if (mOnCaCardChanged != null)  //新卡号与老卡号不同，调用换卡回调
                    mOnCaCardChanged.onCaCardChanged();
                return true;
            } else if (TextUtils.isEmpty(caCardId) && !TextUtils.isEmpty(caCard)) {
                //老卡号为空，新卡号不为空
                caCardId = caCard;
                return true;
            } else {
                //用户信息获取失败
                return false;
            }
        } catch (RemoteException e) {
            Log.i(TAG, "get area code fail RemoteException");
            e.printStackTrace();
            reBind();
        } catch (JSONException e) {
            e.printStackTrace();
            Log.i(TAG, "get area code fail JSONException");
        }
        return false;
    }

    public void setOnCaCardChanged(OnCaCardChanged l) {
        mOnCaCardChanged = l;
    }

    private OnCaCardChanged mOnCaCardChanged;

    public interface OnCaCardChanged {
        void onCaCardChanged();
    }

}
